#!/usr/bin/env python
"""Manages all the known operations that can be performed via
RyCE.  To import a valid command extension it must contain these elements:
1) Filename (w/o extension) the exact same as the classname
2) __opername__='some name'
3) Be inherited from CmdObject in cmdobj.py
4) Have a _pre_execute_() method.
5) Have a _post_execute_() method.
This module check for those things
"""
#-IMPORTS-----------------------------------------------------------------------
import os
import sys
import glob
import logging
import cmdobj
import cmdline
import constants
import cmdfactory
#-CONSTANTS---------------------------------------------------------------------
EXT_FILENAME = 'plugins.dat'
#-CLASSES-----------------------------------------------------------------------
class OperationsManager:
    def __init__(self, p_cf = None):
        """The ops dictionary takes on this format.  {'start':'','info';'uname -a'}
        'start' is a module operation written in Python and 'info' is a basic
        ssh/linux command-line operation.
        """
        self.__log = logging.getLogger(__name__)
        self.ops = {}
        if p_cf is None:
            self.__cf = cmdfactory.CmdFactory()
        else:
            self.__cf = p_cf
        self.__loadDat()
        self.__loadMod()

    def __loadDat(self):
        """Loads the extension.dat file in the extensions dir.
        """
        extDatFilename = '%s%s%s'%(cmdline.options.extsDir,
                                   os.sep,
                                   EXT_FILENAME)
        try:  #Open the if it is there the extension.dat file.
            pFile = open(extDatFilename, 'rb')
            lines = pFile.readlines()
            pFile.close()
            for line in lines:
                line.rsplit()
                if line[0] != '#':
                    tokens = line.split('%$%')
                    self.ops[str(tokens[0])] = str(tokens[1])
            self.__log.debug('%d plugin(s) loaded from %s'%(len(self.ops),
                                                               extDatFilename))
        except:
            self.__log.error('No plugin(s) loaded from %s'%extDatFilename)

    def __loadMod(self):
        """Loads all the plugins in the plugins dir.
        """
        fullNames = glob.glob(cmdline.options.extsDir+os.sep+'*.py')
        for name in fullNames:
            (filePath, fileName) = os.path.split(name)
            (shortName, extension) = os.path.splitext(fileName)
            try:
                __import__(shortName , globals(), locals(), [''])
                if hasattr(sys.modules[shortName], sys.modules[shortName].__name__):
                    t_class = getattr(sys.modules[shortName], sys.modules[shortName].__name__)
                    if hasattr(sys.modules[shortName], '__plugin_name__'):
                        if hasattr(t_class, '_pre_execute'):
                            if hasattr(t_class, '_post_execute'):
                                if issubclass(t_class, cmdobj.CmdObject):
                                    self.__cf.register(sys.modules[shortName].__opername__, t_class)
                                    self.ops[sys.modules[shortName].__opername__] = ''
                                else:
                                    self.__log.debug('(%s) not imported: Is not a subclass of CmdObject (cmdobj.py)'%shortName)
                            else:
                                self.__log.debug('(%s) not imported: Does not have a _post_execute() method.'%shortName)
                        else:
                            self.__log.debug('(%s) not imported: Does not have a _pre_execute() method.'%shortName)
                    else:
                        self.__log.debug('(%s) not imported: Does not have a __plugin_name__ attribute.'%shortName)
                else:
                    self.__log.debug('(%s) not imported: File name does not match __name__ attribute.'%shortName)
            except:
                self.__log.debug('Exception: %s; %s'%(sys.exc_type, shortName))
        self.ops[constants.OP_ENV]  = ''
        self.ops[constants.OP_LIST] = ''
        self.ops[constants.OP_LISTALL] = ''

    def getFactory(self):
        return self.__cf
